﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ComputerArchitecture.Core;
using ComputerArchitecture.Core.Logging;
using ComputerArchitecture.Numbers;
using ComputerArchitecture.Units.Interfaces;

namespace ComputerArchitecture.Units.Shifted
{
    public class ShiftedAdderUnit : LoggingObject, IShiftedAdderUnit
    {
        #region Fields

        private readonly IAdderUnit _adderUnit;
        private readonly ISubstractUnit _substractUnit;

        #endregion

        #region Constructors

        public ShiftedAdderUnit(ILoggingService loggingService, IAdderUnit adderUnit, ISubstractUnit substractUnit)
            : base(loggingService)
        {
            ArgumentValidator.NullValidate(adderUnit);
            _adderUnit = adderUnit;
            ArgumentValidator.NullValidate(substractUnit);
            _substractUnit = substractUnit;
        }

        #endregion

        #region Methods

        #endregion

        public ISignedBitNumber Add(ISignedBitNumber first, ISignedBitNumber second, ISignedBitNumber offset, out bool overflow)
        {
            ArgumentValidator.NullValidate(first);
            ArgumentValidator.NullValidate(second);
            ArgumentValidator.NullValidate(offset);
            ISignedBitNumber firstComplement = _substractUnit.Substract(first, offset, out overflow);
            ISignedBitNumber secondComplement = _substractUnit.Substract(second, offset, out overflow);
            ISignedBitNumber resultComplement = _adderUnit.Add(firstComplement, secondComplement, out overflow);
            return new ShiftedBitNumber(_adderUnit.Add(resultComplement, offset, out overflow));
        }

        ISignedBitNumber IAdderUnit.Add(ISignedBitNumber first, ISignedBitNumber second, out bool overflow)
        {
            return Add(first, second, ShiftedBitNumber.GetOffset(first.Size), out overflow);
        }
    }
}
